package com.sharing.service;

import com.sharing.common.Page;
import com.sharing.common.Result;
import com.sharing.domain.Comments;
import com.sharing.domain.User;
import com.sharing.domain.UserProduction;
import com.sharing.mapper.CommentMapper;
import com.sharing.mapper.UserMapper;
import com.sharing.util.ThreadLocalStorage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import sun.plugin.com.event.COMEventHandler;

import javax.jws.soap.SOAPBinding;
import java.util.*;

/**
 * @author MingTian
 * @version 1.0
 * @description TODO
 * @date 2023/4/3 10:39
 */
@Service
public class CommentService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private UserProductionService userProductionService;

    /**
     * 根据作品id查询该作品下所有的评论（评论需要区分是否为该作品的直接评论）的业务层方法
     * @param productionId
     * @return
     */
    public Result<Page<Comments>> selectCommentsByProductionId(Integer productionId, Integer page, Integer size) {
        // 查询作品的直接评论总数
        Integer total = commentMapper.selectCommentsNumByProductionId(productionId);

        // 如果page过大，返回数据为空
        if (total == 0 || (page - 1) * size >= total) {
            return new Result<>(0, new Page<>(total, size, new ArrayList<>()));
        }

        // 查询出直接评论的评论（分页）
        List<Comments> comments = commentMapper.selectCommentsByProductionId(productionId, (page - 1) * size, size);

        for (Comments comment1 : comments) {
            Integer commentId1 = comment1.getId();
            Result<Page<Comments>> result = selectCommentsByCommentId(commentId1, page, size);
            comment1.setComments(result.getData().getResult());
        }

        return new Result<>(0, new Page<>(total, size, comments));
    }

    /**
     * 根据评论id查询该评论的所有直接或间接评论的业务层方法
     * @param commentId
     * @param page
     * @param size
     * @return
     */
    public Result<Page<Comments>> selectCommentsByCommentId(Integer commentId, Integer page, Integer size) {
        // 查询评论的直接评论总数
        Integer total = commentMapper.selectCommentsNumByCommentId(commentId);

        // 如果page过大，返回数据为空
        if (total == 0 || (page - 1) * size >= total) {
            return new Result<>(0, new Page<>(total, size, new ArrayList<>()));
        }

        // 查询出直接评论的评论（分页）
        List<Comments> comments = commentMapper.selectCommentsByCommentId(commentId, (page - 1) * size, size);

        for (Comments comment1 : comments) {
            Integer commentId1 = comment1.getId();
            Result<Page<Comments>> comments1 = selectCommentsByCommentId(commentId1, page, size);
            comment1.setComments(comments1.getData().getResult());
        }

        return new Result<>(0, new Page<>(total, size, comments));
    }

    /**
     * 根据用户id查询该用户所发表的评论
     * @param userId
     * @param page
     * @param size
     * @return
     */
    public Result<Page<Comments>> selectCommentsByUserId(Integer userId, Integer page, Integer size) {
        User loginUser = ThreadLocalStorage.getUser();
        if (loginUser == null) {
            synchronized (this) {
                if (loginUser == null) {
                    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                    loginUser = userMapper.selectUserByUserName(authentication.getName());
                    ThreadLocalStorage.setUser(loginUser);
                }
            }
        }
        if (userId != null && loginUser.getId() != userId) {
            return new Result<>(1, "传入参数有误");
        }
        userId = loginUser.getId();
        // 查询总数
        Integer total = commentMapper.selectCommentsNumByUserId(userId);

        // 查询评论
        List<Comments> comments = commentMapper.selectCommentsByUserId(userId, (page - 1) * size, size);

        Page<Comments> page1 = new Page<>(total, size, comments);

        return new Result<>(0, page1);
    }

    /**
     * 新增评论的业务层方法
     * @param comments
     * @return
     */
    public Result<Comments> insertComment(Comments comments) {
        // 校验参数
        if (comments.getUserId() == null) {
            return new Result<>(1, "参数不完整");
        }
        if (comments.getProductionId() == null && comments.getCommentId() == null) {
            return new Result<>(1, "参数不完整");
        }

        if (comments.getCommentId() != null) {
            // 若是评论某一条评论的
            Integer productionId = commentMapper.selectCommentById(comments.getCommentId()).getProductionId();
            if (comments.getProductionId() != null && !Objects.equals(productionId, comments.getProductionId())) {
                return new Result<>(1, "参数有误");
            }
            comments.setProductionId(productionId);
            Integer rows = commentMapper.insertComment(comments);
            if (rows == 0) {
                return new Result<>(1, "新增失败");
            }
            return new Result<>(0, comments);
        } else {
            // 若是对某一作品的评论
            comments.setCommentId(0);
            Integer rows = commentMapper.insertComment(comments);
            if (rows == 0) {
                return new Result<>(1, "新增失败");
            }

            return new Result<>(0, comments);
        }
    }

    /**
     * 根据主键删除评论的业务层方法
     * @param id
     * @return
     */
    public Result<Integer> deleteCommentById(Integer id) {
        Comments comments = commentMapper.selectCommentById(id);
        if (comments == null) {
            return new Result<>(1, "该评论不存在");
        }
//        if (comments.getCommentId() != 0) {
//            //
//        }

        Integer rows = commentMapper.deleteComment(id);

        if (rows == 0) {
            return new Result<>(1, "删除失败");
        }

        return new Result<>(0, rows);
    }

    /**
     * 根据主键删除评论的业务层方法——多个
     * @param ids
     * @return
     */
    public Result<Integer> deleteCommentsByIds(List<Integer> ids) {
        if (ids == null || ids.size() == 0) {
            return new Result<>(1, "参数传入有误");
        }

        Integer rows = commentMapper.deleteCommentsByIds(ids);

        if (rows < ids.size()) {
            return new Result<>(0, (ids.size() - rows) + "个评论删除失败");
        }

        return new Result<>(0, rows);
    }

    /**
     * 通过评论id查询直接父级评论的业务层方法————若返回数据为空，表示该评论为顶级父级评论
     * @param commentId
     * @return
     */
    public Result<Comments> selectParentCommentByCommentId(Integer commentId) {
        Comments curComment = commentMapper.selectCommentById(commentId);
        if (curComment == null) {
            return new Result<>(1, "该条评论不存在或者已删除");
        }

        if (curComment.getCommentId() == 0) {
            return new Result<>(1, "该条评论没有父级评论");
        }

        Comments parentComment = commentMapper.selectCommentById(curComment.getCommentId());

        return new Result<>(0, parentComment);
    }

    /**
     * 通过评论id查询顶级父级评论————若返回数据为空，表示该评论为顶级父级评论
     * @param commentId
     * @return
     */
    public Result<Comments> selectTopParentCommentByCommentId(Integer commentId) {
        Comments curComment = commentMapper.selectCommentById(commentId);
        if (curComment == null) {
            return new Result<>(1, "该条评论不存在或者已删除");
        }

        if (curComment.getCommentId() == 0) {
            return new Result<>(1, "该条评论没有父级评论");
        }

        while (curComment.getCommentId() != 0) {
            Result<Comments> result = selectParentCommentByCommentId(curComment.getId());
            curComment = result.getData();
        }

        return new Result<>(0, curComment);
    }

    /**
     * 通过评论id查询顶级作品的业务层方法
     * @param commentId
     * @return
     */
    public Result<UserProduction> selectProductionByCommentId(Integer commentId) {
        Comments curComment = commentMapper.selectCommentById(commentId);
        if (curComment == null) {
            return new Result<>(1, "该条评论不存在或者已删除");
        }

        if (curComment.getCommentId() == 0) {
            return userProductionService.selectUserProductionById(curComment.getProductionId());
        }

        Result<Comments> result = selectTopParentCommentByCommentId(commentId);
        Result<UserProduction> result1 = userProductionService.selectUserProductionById(result.getData().getProductionId());

        return result1;
    }
}
